﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using GameFramework;

namespace TowerDefence_Zombie.Data
{
    public class Tower : IReference
    {
        private TowerData towerData;

        public int TowerDataId
        {
            get;
            private set;
        }

        public int Level
        {
            get;
            private set;
        }

        public int SerialId
        {
            get;
            private set;
        }

        public string Icon
        {
            get
            {
                return towerData.Icon;
            }
        }

        public IntVector2 Dimensions
        {
            get
            {
                return towerData.Dimensions;
            }
        }

        public string Type
        {
            get
            {
                return towerData.Type;
            }
        }

        public int MaxLevel
        {
            get
            {
                return towerData.GetMaxLevel();
            }
        }

        public bool IsMaxLevel
        {
            get
            {
                return Level >= towerData.GetMaxLevel();
            }
        }

        public float Damage
        {
            get
            {
                return GetDamage(Level);
            }
        }

        public float FireRate
        {
            get
            {
                return GetFireRate(Level);
            }
        }

        public float SpeedDownRate
        {
            get
            {
                return GetSpeedDownRate(Level);
            }
        }

        public float ContinuousDamage
        {
            get
            {
                return GetContinuousDamage(Level);
            }
        }

        public float Range
        {
            get
            {
                return GetRange(Level);
            }
        }

        public int EntityId
        {
            get
            {
                return towerData.EntityId;
            }
        }

        public int ProjectileEntityId
        {
            get
            {
                return towerData.ProjectileEntityId;
            }
        }

        public string ProjectileType
        {
            get
            {
                return towerData.ProjectileType;
            }
        }

        public bool IsMultiAttack
        {
            get
            {
                return towerData.IsMultiAttack;
            }
        }


        public int LevelEntityId
        {
            get
            {
                return GetLevelEntityId(Level);
            }
        }

        public bool IsUpgrade
        {
            get;
            private set;
        }

        public Tower()
        {
            towerData = null;
            Level = 0;
            SerialId = 0;
        }

        public int GetLevelEntityId(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                return towerData.GetTowerLevelData(level).EntityId;
            }
        }

        public float GetDamage(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                var towerStar = GameEntry.Data.GetData<DataPlayer>().GetTowerStar(TowerDataId);
                var towerStarData = towerData.GetStarData(towerStar);
                var starAdditionalDamage = towerStarData.DamageAddition;
                return towerData.GetTowerLevelData(level).Damage + starAdditionalDamage;
            }
        }

        public float GetFireRate(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                var towerStar = GameEntry.Data.GetData<DataPlayer>().GetTowerStar(TowerDataId);
                var towerStarData = towerData.GetStarData(towerStar);
                var starAdditionalFireRate = towerStarData.FireRateAddition;
                return towerData.GetTowerLevelData(level).FireRate + starAdditionalFireRate;
            }
        }

        public float GetSpeedDownRate(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                var towerStar = GameEntry.Data.GetData<DataPlayer>().GetTowerStar(TowerDataId);
                var towerStarData = towerData.GetStarData(towerStar);
                var starAdditionalSlow = towerStarData.SpeedDownRateAddition;
                return towerData.GetTowerLevelData(level).SpeedDownRate + starAdditionalSlow;
            }
        }

        public float GetContinuousDamage(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                var towerStar = GameEntry.Data.GetData<DataPlayer>().GetTowerStar(TowerDataId);
                var towerStarData = towerData.GetStarData(towerStar);
                var starAdditionalCDamage = towerStarData.ContinuousDamageAddition;
                return towerData.GetTowerLevelData(level).ContinuousDamage + starAdditionalCDamage;
            }
        }

        public float GetRange(int level)
        {
            if (level < 0 || level > MaxLevel)
            {
                Log.Error("Param level '{0} invaild'", level);
                return 0;
            }
            else
            {
                var towerStar = GameEntry.Data.GetData<DataPlayer>().GetTowerStar(TowerDataId);
                var towerStarData = towerData.GetStarData(towerStar);
                var starAdditionalRange = towerStarData.RangeAddition;
                return towerData.GetTowerLevelData(level).Range + starAdditionalRange;
            }
        }

        public static Tower Create(TowerData towerData, int serialId, int level = 0, bool isUpgrade = false)
        {
            Tower tower = ReferencePool.Acquire<Tower>();
            tower.towerData = towerData;
            tower.Level = level;
            tower.IsUpgrade = isUpgrade;
            tower.SerialId = serialId;
            tower.TowerDataId = towerData.Id;
            return tower;
        }

        public void Clear()
        {
            towerData = null;
            Level = 0;
            SerialId = 0;
        }
    }
}


